package com.winchain.chainbill.bill.base.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.shell.bee.base.utils.DateUtil;
import com.shell.bee.base.utils.JsonUtil;
import com.shell.bee.base.utils.StringUtil;
import com.shell.bee.base.utils.SystemUtil;
import com.shell.bee.file.po.PubFile;
import com.shell.bee.file.service.PubFileService;
import com.shell.bee.invoince.service.InvBasService;
import com.shell.bee.invoince.vo.InvBasVo;
import com.shell.bee.persistence.service.impl.PersistentServiceImpl;
import com.winchain.chainbill.bill.base.dao.CbAttDao;
import com.winchain.chainbill.bill.base.po.CbAtt;
import com.winchain.chainbill.bill.base.service.CbAttService;
import com.winchain.chainbill.bill.biz.query.vo.CbRecVo;
import com.winchain.chainbill.bill.biz.send.vo.BillAttInvoice;
import com.winchain.chainbill.bill.biz.transfer.vo.BillTransfer;
import com.winchain.chainbill.serfee.vo.SerFeeVo;
import com.winchain.chainbill.tbill.biz.vo.TbRecVo;

@Service("cbAttService")
public class CbAttServiceImpl extends PersistentServiceImpl<CbAtt> implements CbAttService {
	@Autowired
	private CbAttDao cbAttDao;
	@Autowired
	private PubFileService pubFileService;
	@Autowired
	private InvBasService invBasService;

	public void setAtt(CbRecVo cbRecVo) {
		String bizId = cbRecVo.getBizId();
		if (StringUtil.notEmpty(cbRecVo.getTxId())) {
			bizId = cbRecVo.getTxId();
		}
		CbAtt cbAtt = new CbAtt();
		if (!StringUtil.emptyAndNull(cbRecVo.getDctBillId())) {
			cbAtt.setBillId(cbRecVo.getDctBillId());
		} else {
			cbAtt.setBillId(cbRecVo.getBillId());
		}
		cbAtt.setBizId(bizId);
		String contractNo = "";
		String invoiceNo = "";

		List<CbAtt> cbAtts = this.cbAttDao.select(cbAtt);
		List<CbAtt> contractNos = new ArrayList();
		List<CbAtt> invoiceNos = new ArrayList();
		List<PubFile> contractFiles = new ArrayList();
		List<List<PubFile>> invoiceFiles = new ArrayList();
		List<BillAttInvoice> billAttInvoices = new ArrayList();
		if ((cbAtts == null) || (cbAtts.size() == 0)) {
			return;
		}
		for (CbAtt ca : cbAtts) {
			if ("4".equals(ca.getAttType())) {
				contractNo = contractNo + "," + ca.getAttNo();
				contractNos.add(ca);

				PubFile file = new PubFile();
				file.setRelateId(ca.getAttId());
				file.setFileType("4");
				List<PubFile> files = this.pubFileService.selectFiles(file);
				contractFiles.addAll(files);
			} else if ("6".equals(ca.getAttType())) {
				invoiceNo = invoiceNo + "," + ca.getAttNo();
				invoiceNos.add(ca);

				PubFile file = new PubFile();
				file.setRelateId(ca.getAttId());
				file.setFileType("6");
				List<PubFile> files = this.pubFileService.selectFiles(file);
				invoiceFiles.add(files);
				InvBasVo invBasVo = this.invBasService.selectInvBasByAttId(ca.getAttId());
				if (invBasVo != null) {
					BillAttInvoice attInvoice = new BillAttInvoice();
					BeanUtils.copyProperties(invBasVo, attInvoice);
					if (invBasVo.getInvAmt() != null) {
						attInvoice.setInvAmt(invBasVo.getInvAmt().toString());
					}
					if (invBasVo.getTax() != null) {
						attInvoice.setTax(invBasVo.getTax().toString());
					}
					if (invBasVo.getTaxRate() != null) {
						attInvoice.setTaxRate(invBasVo.getTaxRate().toString());
					}
					attInvoice.setAttId(ca.getAttId());
					if ((files != null) && (files.size() > 0)) {
						attInvoice.setFileId(((PubFile) files.get(0)).getFileId());
					}
					billAttInvoices.add(attInvoice);
				}
			}
		}
		if (contractNo.length() > 0) {
			contractNo = contractNo.substring(1);
		}
		if (invoiceNo.length() > 0) {
			invoiceNo = invoiceNo.substring(1);
		}
		cbRecVo.setContractNo(contractNo);
		cbRecVo.setInvoiceNo(invoiceNo);
		cbRecVo.setContractNos(contractNos);
		cbRecVo.setInvoiceNos(invoiceNos);
		cbRecVo.setContractFiles(contractFiles);
		cbRecVo.setInvoiceFiles(invoiceFiles);
		cbRecVo.setBillAttInvoices(billAttInvoices);
	}

	public void setAtt(List<BillTransfer> transfers) {
		for (BillTransfer bt : transfers) {
			if (!StringUtil.empty(bt.getXfeId())) {
				CbAtt cbAtt = new CbAtt();
				cbAtt.setBillId(bt.getBillId());
				cbAtt.setBizId(bt.getXfeId());
				cbAtt.setAttType("6");
				List<CbAtt> cbAtts = this.cbAttDao.select(cbAtt);
				if ((cbAtts != null) && (cbAtts.size() != 0)) {
					String invoiceNo = "";
					List<BillAttInvoice> billAttInvoices = new ArrayList();
					for (CbAtt cb : cbAtts) {
						if (invoiceNo.equals("")) {
							invoiceNo = cb.getAttNo();
						} else {
							invoiceNo = invoiceNo + "," + cb.getAttNo();
						}
						PubFile file = new PubFile();
						file.setRelateId(cb.getAttId());
						file.setFileType("6");
						List<PubFile> files = this.pubFileService.selectFiles(file);
						InvBasVo invBasVo = this.invBasService.selectInvBasByAttId(cb.getAttId());
						if (invBasVo != null) {
							BillAttInvoice attInvoice = new BillAttInvoice();
							BeanUtils.copyProperties(invBasVo, attInvoice);
							if (invBasVo.getInvAmt() != null) {
								attInvoice.setInvAmt(invBasVo.getInvAmt().toString());
							}
							if (invBasVo.getTax() != null) {
								attInvoice.setTax(invBasVo.getTax().toString());
							}
							if (invBasVo.getTaxRate() != null) {
								attInvoice.setTaxRate(invBasVo.getTaxRate().toString());
							}
							attInvoice.setAttId(cb.getAttId());
							if ((files != null) && (files.size() > 0)) {
								attInvoice.setFileId(((PubFile) files.get(0)).getFileId());
							}
							billAttInvoices.add(attInvoice);
						}
					}
					bt.setInvoiceNo(invoiceNo);
					bt.setBillAttInvoices(billAttInvoices);
				}
			}
		}
	}

	public void setTbAtt(TbRecVo tbRecVo) {
		CbAtt cbAtt = new CbAtt();
		if (!StringUtil.emptyAndNull(tbRecVo.getDctId())) {
			cbAtt.setBizId(tbRecVo.getDctId());
		}
		cbAtt.setBillId(tbRecVo.getBillId());

		List<CbAtt> cbAtts = this.cbAttDao.select(cbAtt);
		List<PubFile> contractFiles = new ArrayList();
		List<List<PubFile>> invoiceFiles = new ArrayList();
		List<BillAttInvoice> billAttInvoices = new ArrayList();
		if ((cbAtts == null) || (cbAtts.size() == 0)) {
			return;
		}
		String relState = "1";
		if ("S007".equals(tbRecVo.getBillState())) {
			relState = "0";
		}
		for (CbAtt ca : cbAtts) {
			if ("10".equals(ca.getAttType())) {
				PubFile file = new PubFile();
				file.setRelateId(ca.getAttId());
				file.setFileType("10");
				List<PubFile> files = this.pubFileService.selectFiles(file);
				contractFiles.addAll(files);
			} else if ("11".equals(ca.getAttType())) {
				PubFile file = new PubFile();
				file.setRelateId(ca.getAttId());
				file.setFileType("11");
				List<PubFile> files = this.pubFileService.selectFiles(file);
				invoiceFiles.add(files);

				InvBasVo invBasVo = this.invBasService.selectInvBasByAttIdAndState(ca.getAttId(), relState);
				if (invBasVo != null) {
					BillAttInvoice attInvoice = new BillAttInvoice();
					BeanUtils.copyProperties(invBasVo, attInvoice);
					if (invBasVo.getInvAmt() != null) {
						attInvoice.setInvAmt(invBasVo.getInvAmt().toString());
					}
					if (invBasVo.getTax() != null) {
						attInvoice.setTax(invBasVo.getTax().toString());
					}
					if (invBasVo.getTaxRate() != null) {
						attInvoice.setTaxRate(invBasVo.getTaxRate().toString());
					}
					attInvoice.setAttId(ca.getAttId());
					if ((files != null) && (files.size() > 0)) {
						attInvoice.setFileId(((PubFile) files.get(0)).getFileId());
					}
					billAttInvoices.add(attInvoice);
				}
			}
		}
		tbRecVo.setContractFiles(contractFiles);
		tbRecVo.setInvoiceFiles(invoiceFiles);
		tbRecVo.setBillAttInvoices(billAttInvoices);
	}

	public void setSerFeeTbAtt(SerFeeVo serFeeVo) {
		TbRecVo tbRecVo = new TbRecVo();
		tbRecVo.setDctId(serFeeVo.getDctId());
		tbRecVo.setBillId(serFeeVo.getBillId());
		setTbAtt(tbRecVo);
		serFeeVo.setBillAttInvoices(tbRecVo.getBillAttInvoices());
		serFeeVo.setContractFiles(tbRecVo.getContractFiles());
		serFeeVo.setInvoiceFiles(tbRecVo.getInvoiceFiles());
	}

	public Map<List<String>, List<BillAttInvoice>> saveCbAtt(String billId, String bizId, String contractFileIds,
			String attInvoices, String contractType, String invoiceType) throws Exception {
		if (!StringUtil.emptyAndNull(contractFileIds)) {
			CbAtt att = saveOrUpdate(billId, bizId, contractType, "");
			this.pubFileService.setRelateId(contractFileIds, att.getAttId(), contractType);
		}
		Map<List<String>, List<BillAttInvoice>> result = new HashMap();
		if (!StringUtil.emptyAndNull(attInvoices)) {
			List<BillAttInvoice> attInvoiceList = JsonUtil.fromJsonArray(attInvoices, BillAttInvoice.class);
			List<String> invoiceNos = new ArrayList();
			List<BillAttInvoice> savecbAtts = new ArrayList();
			Map<String, String> map = new HashMap();
			for (BillAttInvoice attInvoice : attInvoiceList) {
				if ((map.size() == 0) || (!map.containsKey(attInvoice.getInvNo() + attInvoice.getInvCode()))) {
					invoiceNos.add(attInvoice.getInvNo());
					CbAtt att = saveOrUpdate(billId, bizId, invoiceType, attInvoice.getInvNo());

					PubFile pubFile = (PubFile) this.pubFileService.selectByKey(attInvoice.getFileId());
					if (pubFile != null) {
						PubFile newFile = new PubFile();
						BeanUtils.copyProperties(pubFile, newFile);
						newFile.setFileId(SystemUtil.getUUID());
						this.pubFileService.save(newFile);
						this.pubFileService.setRelateId(newFile.getFileId(), att.getAttId(), invoiceType);
					} else {
						this.pubFileService.setRelateId(attInvoice.getFileId(), att.getAttId(), invoiceType);
					}
					attInvoice.setAttId(att.getAttId());
					savecbAtts.add(attInvoice);
					map.put(attInvoice.getInvNo() + attInvoice.getInvCode(),
							attInvoice.getInvNo() + attInvoice.getInvCode());
				}
			}
			result.put(invoiceNos, savecbAtts);
		}
		return result;
	}

	private CbAtt saveOrUpdate(String billId, String bizId, String attType, String attNo) {
		CbAtt att = getOneCbAtt(billId, bizId, attType, attNo);
		if (att == null) {
			att = new CbAtt();
			att.setAttId(SystemUtil.getUUID());
			att.setAttNo(attNo);
			att.setBillId(billId);
			att.setBizId(bizId);
			att.setAttType(attType);
			att.setCreateTime(DateUtil.getSystemDateTime());
			this.cbAttDao.insert(att);
		} else {
			if ((!StringUtil.emptyAndNull(bizId)) && (StringUtil.emptyAndNull(att.getBizId()))) {
				att.setBizId(bizId);
			}
			att.setCreateTime(DateUtil.getSystemDateTime());
			this.cbAttDao.updateByPrimaryKey(att);
		}
		return att;
	}

	private CbAtt getOneCbAtt(String billId, String bizId, String attType, String attNo) {
		CbAtt att = new CbAtt();
		att.setBillId(billId);
		if (!StringUtil.emptyAndNull(bizId)) {
			att.setBizId(bizId);
		}
		att.setAttType(attType);
		att.setAttNo(attNo);
		return (CbAtt) this.cbAttDao.selectOne(att);
	}
}
